using Senparc.Weixin.Helpers;
using Senparc.Weixin.QY.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Xml.Linq;
namespace Senparc.Weixin.QY.Helpers
{
	public static class EntityHelper
	{
		public static void FillEntityWithXml<T>(this T entity, XDocument doc) where T : class, new()
		{
			T arg_0F_0;
			if ((arg_0F_0 = entity) == null)
			{
				arg_0F_0 = Activator.CreateInstance<T>();
			}
			entity = arg_0F_0;
			XElement root = doc.Root;
			PropertyInfo[] properties = entity.GetType().GetProperties();
			PropertyInfo[] array = properties;
			for (int i = 0; i < array.Length; i++)
			{
				PropertyInfo propertyInfo = array[i];
				string name = propertyInfo.Name;
				if (root.Element(name) != null)
				{
					string name2;
					switch (name2 = propertyInfo.PropertyType.Name)
					{
					case "DateTime":
						propertyInfo.SetValue(entity, DateTimeHelper.GetDateTimeFromXml(root.Element(name).Value), null);
						goto IL_68C;
					case "Boolean":
						if (name == "FuncFlag")
						{
							propertyInfo.SetValue(entity, root.Element(name).Value == "1", null);
							goto IL_68C;
						}
						break;
					case "Int32":
						propertyInfo.SetValue(entity, int.Parse(root.Element(name).Value), null);
						goto IL_68C;
					case "Int64":
						propertyInfo.SetValue(entity, long.Parse(root.Element(name).Value), null);
						goto IL_68C;
					case "Double":
						propertyInfo.SetValue(entity, double.Parse(root.Element(name).Value), null);
						goto IL_68C;
					case "RequestMsgType":
					case "ResponseMsgType":
					case "ThirdPartyInfo":
					case "Event":
						goto IL_68C;
					case "List`1":
					{
						Type[] genericArguments = propertyInfo.PropertyType.GetGenericArguments();
						if (genericArguments[0].Name == "Article")
						{
							List<Article> list = new List<Article>();
							foreach (XElement current in root.Element(name).Elements("item"))
							{
								Article article = new Article();
								article.FillEntityWithXml(new XDocument(new object[]
								{
									current
								}));
								list.Add(article);
							}
							propertyInfo.SetValue(entity, list, null);
							goto IL_68C;
						}
						if (genericArguments[0].Name == "MpNewsArticle")
						{
							List<MpNewsArticle> list2 = new List<MpNewsArticle>();
							foreach (XElement current2 in root.Elements(name))
							{
								MpNewsArticle mpNewsArticle = new MpNewsArticle();
								mpNewsArticle.FillEntityWithXml(new XDocument(new object[]
								{
									current2
								}));
								list2.Add(mpNewsArticle);
							}
							propertyInfo.SetValue(entity, list2, null);
							goto IL_68C;
						}
						if (genericArguments[0].Name == "PicItem")
						{
							List<PicItem> list3 = new List<PicItem>();
							foreach (XElement current3 in root.Elements(name).Elements("item"))
							{
								PicItem picItem = new PicItem();
								string value = current3.Element("PicMd5Sum").Value;
								Md5Sum item = new Md5Sum
								{
									PicMd5Sum = value
								};
								picItem.item = item;
								list3.Add(picItem);
							}
							propertyInfo.SetValue(entity, list3, null);
							goto IL_68C;
						}
						goto IL_68C;
					}
					case "Image":
					{
						Image image = new Image();
						image.FillEntityWithXml(new XDocument(new object[]
						{
							root.Element(name)
						}));
						propertyInfo.SetValue(entity, image, null);
						goto IL_68C;
					}
					case "Voice":
					{
						Voice voice = new Voice();
						voice.FillEntityWithXml(new XDocument(new object[]
						{
							root.Element(name)
						}));
						propertyInfo.SetValue(entity, voice, null);
						goto IL_68C;
					}
					case "Video":
					{
						Video video = new Video();
						video.FillEntityWithXml(new XDocument(new object[]
						{
							root.Element(name)
						}));
						propertyInfo.SetValue(entity, video, null);
						goto IL_68C;
					}
					case "ScanCodeInfo":
					{
						ScanCodeInfo scanCodeInfo = new ScanCodeInfo();
						scanCodeInfo.FillEntityWithXml(new XDocument(new object[]
						{
							root.Element(name)
						}));
						propertyInfo.SetValue(entity, scanCodeInfo, null);
						goto IL_68C;
					}
					case "SendLocationInfo":
					{
						SendLocationInfo sendLocationInfo = new SendLocationInfo();
						sendLocationInfo.FillEntityWithXml(new XDocument(new object[]
						{
							root.Element(name)
						}));
						propertyInfo.SetValue(entity, sendLocationInfo, null);
						goto IL_68C;
					}
					case "SendPicsInfo":
					{
						SendPicsInfo sendPicsInfo = new SendPicsInfo();
						sendPicsInfo.FillEntityWithXml(new XDocument(new object[]
						{
							root.Element(name)
						}));
						propertyInfo.SetValue(entity, sendPicsInfo, null);
						goto IL_68C;
					}
					case "BatchJobInfo":
					{
						BatchJobInfo batchJobInfo = new BatchJobInfo();
						batchJobInfo.FillEntityWithXml(new XDocument(new object[]
						{
							root.Element(name)
						}));
						propertyInfo.SetValue(entity, batchJobInfo, null);
						goto IL_68C;
					}
					}
					propertyInfo.SetValue(entity, root.Element(name).Value, null);
				}
				IL_68C:;
			}
		}
		public static XDocument ConvertEntityToXml<T>(this T entity) where T : class, new()
		{
			T arg_16_0;
			if ((arg_16_0 = entity) == null)
			{
				arg_16_0 = Activator.CreateInstance<T>();
			}
			entity = arg_16_0;
			XDocument xDocument = new XDocument();
			xDocument.Add(new XElement("xml"));
			XElement root = xDocument.Root;
			List<string> list = new List<string>
			{
				"ToUserName",
				"FromUserName",
				"CreateTime",
				"MsgType"
			};
			if (entity is ResponseMessageNews)
			{
				list.AddRange(new string[]
				{
					"ArticleCount",
					"Articles",
					"FuncFlag",
					"Title ",
					"Description ",
					"PicUrl",
					"Url"
				});
			}
			else
			{
				if (entity is ResponseMessageMpNews)
				{
					list.AddRange(new string[]
					{
						"MpNewsArticleCount",
						"MpNewsArticles",
						"FuncFlag",
						"Title ",
						"Description ",
						"PicUrl",
						"Url"
					});
				}
				else
				{
					if (entity is ResponseMessageImage)
					{
						list.AddRange(new string[]
						{
							"Image",
							"MediaId "
						});
					}
					else
					{
						if (entity is ResponseMessageVoice)
						{
							list.AddRange(new string[]
							{
								"Voice",
								"MediaId "
							});
						}
						else
						{
							if (entity is ResponseMessageVideo)
							{
								list.AddRange(new string[]
								{
									"Video",
									"MediaId ",
									"Title",
									"Description"
								});
							}
							else
							{
								list.AddRange(new string[]
								{
									"Content",
									"FuncFlag"
								});
							}
						}
					}
				}
			}
			list.AddRange(new string[]
			{
				"AgentID"
			});
			Func<string, int> orderByPropName = new Func<string, int>(list.IndexOf);
			List<PropertyInfo> list2 = (
				from p in entity.GetType().GetProperties()
				orderby orderByPropName(p.Name)
				select p).ToList<PropertyInfo>();
			foreach (PropertyInfo current in list2)
			{
				string name = current.Name;
				if (name == "Articles")
				{
					XElement xElement = new XElement("Articles");
					List<Article> list3 = current.GetValue(entity, null) as List<Article>;
					foreach (Article current2 in list3)
					{
						IEnumerable<XElement> content = current2.ConvertEntityToXml<Article>().Root.Elements();
						xElement.Add(new XElement("item", content));
					}
					root.Add(xElement);
				}
				else
				{
					if (name == "MpNewsArticles")
					{
						XElement xElement2 = new XElement("MpNewsArticles");
						List<MpNewsArticle> list4 = current.GetValue(entity, null) as List<MpNewsArticle>;
						foreach (MpNewsArticle current3 in list4)
						{
							IEnumerable<XElement> content2 = current3.ConvertEntityToXml<MpNewsArticle>().Root.Elements();
							xElement2.Add(content2);
						}
						root.Add(xElement2);
					}
					else
					{
						if (name == "Image" || name == "Video" || name == "Voice")
						{
							XElement xElement3 = new XElement(name);
							object value = current.GetValue(entity, null);
							IEnumerable<XElement> content3 = value.ConvertEntityToXml<object>().Root.Elements();
							xElement3.Add(content3);
							root.Add(xElement3);
						}
						else
						{
							if (name == "KfAccount")
							{
								root.Add(new XElement(name, current.GetValue(entity, null).ToString().ToLower()));
							}
							else
							{
								string name2;
								switch (name2 = current.PropertyType.Name)
								{
								case "String":
									root.Add(new XElement(name, new XCData((current.GetValue(entity, null) as string) ?? "")));
									continue;
								case "DateTime":
									root.Add(new XElement(name, DateTimeHelper.GetWeixinDateTime((DateTime)current.GetValue(entity, null))));
									continue;
								case "Boolean":
									if (name == "FuncFlag")
									{
										root.Add(new XElement(name, ((bool)current.GetValue(entity, null)) ? "1" : "0"));
										continue;
									}
									break;
								case "ResponseMsgType":
									root.Add(new XElement(name, new XCData(current.GetValue(entity, null).ToString().ToLower())));
									continue;
								case "Article":
									root.Add(new XElement(name, current.GetValue(entity, null).ToString().ToLower()));
									continue;
								case "MpNewsArticle":
									root.Add(new XElement(name, current.GetValue(entity, null).ToString().ToLower()));
									continue;
								}
								root.Add(new XElement(name, current.GetValue(entity, null)));
							}
						}
					}
				}
			}
			return xDocument;
		}
		public static string ConvertEntityToXmlString<T>(this T entity) where T : class, new()
		{
			return entity.ConvertEntityToXml<T>().ToString();
		}
		public static T CreateResponseMessage<T>(this IRequestMessageBase requestMessage) where T : ResponseMessageBase
		{
			return ResponseMessageBase.CreateFromRequestMessage<T>(requestMessage);
		}
		public static IResponseMessageBase CreateResponseMessage(this string xml)
		{
			return ResponseMessageBase.CreateFromResponseXml(xml);
		}
	}
}
